/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.acworks.acroute;

import com.acworks.acroute.impl.DatacenterImpl;
import com.acworks.acroute.impl.SpaceImpl;
import java.util.List;

/**
 *
 * @author nikita
 */
public class DatacenterFactory {

    private DatacenterFactory() {
    }

    /**     
     * @param width
     * @param height
     * @param gridIntegers
     * @return a valid grid of Spaces
     * @throws InvalidDatacenterDefinitionException if input params are invalid
     */
    public static Datacenter buildDatacenter(int width, int height, List<Integer> gridIntegers) throws InvalidDatacenterDefinitionException {
        assert gridIntegers != null;
        assert width > 0;
        assert height > 0;

        if (width * height != gridIntegers.size()) {
            throw new InvalidDatacenterDefinitionException("invalid input: number of supplied integers does not equal width * height");
        }

        boolean startFound = false;
        boolean endFound = false;

        final Space[][] grid = new Space[width][height];

        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                final Integer inputInt = gridIntegers.get(y * width + x);

                SpaceType type = SpaceType.get(inputInt);
                if (type == null) {
                    throw new IllegalArgumentException("illegal room input: " + inputInt);
                }

                if (type == SpaceType.START_SPACE) {
                    if (startFound) {
                        throw new InvalidDatacenterDefinitionException("space of type " + type + " declared multiple times");
                    } else {
                        startFound = true;
                    }
                }

                if (type == SpaceType.END_SPACE) {
                    if (endFound) {
                        throw new InvalidDatacenterDefinitionException("space of type " + type + " declared multiple times");
                    } else {
                        endFound = true;
                    }
                }

                Space space = new SpaceImpl(type);

                grid[x][y] = space;
            }
        }

        if (!startFound) {
            throw new InvalidDatacenterDefinitionException("space of type " + SpaceType.START_SPACE + " not found");
        }

        if (!endFound) {
            throw new InvalidDatacenterDefinitionException("space of type " + SpaceType.END_SPACE + " not found");
        }

        return new DatacenterImpl(grid);
    }
}
